package cn.andy.mybatis.utils;

import org.apache.commons.lang3.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.format.TextStyle;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class LocalDateUtils {

    private final static String DEFAULT_PATTERN_DATE_TIME = "yyyy-MM-dd HH:mm:ss";

    private final static String DEFAULT_PATTERN_DATE = "yyyy-MM-dd";

    /**
     * get current date FULL/LONG/MEDIUM/SHORT
     * format 2019-8-14-->MEDIUM
     * 2019年8月14日 星期三 -->FULL
     * 2019年8月14日 -->LONG
     * 19-8-14 -->SHORT
     *
     * @param pattern
     * @return string
     */
    public static String getCurrentDateFormatStyle(String pattern) {
        return LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(
                StringUtils.isEmpty(pattern) ?
                        FormatStyle.MEDIUM : "FULL".equalsIgnoreCase(pattern) ?
                        FormatStyle.FULL : "LONG".equalsIgnoreCase(pattern) ?
                        FormatStyle.LONG : "SHORT".equalsIgnoreCase(pattern) ?
                        FormatStyle.SHORT : FormatStyle.MEDIUM));
    }

    /**
     * get current year
     * year
     *
     * @return String
     */
    public static String getYear() {
        return String.valueOf(LocalDate.now().getYear());
    }

    /**
     * get number month 1 , 2 , 3
     * month
     *
     * @return String
     */
    public static String getMonthValue() {
        return String.valueOf(LocalDate.now().getMonthValue());
    }


    /**
     * get characters month 1 <==> 一月
     *
     * @return String
     */
    public static String getMonth() {
        return LocalDate.now().getMonth().getDisplayName(TextStyle.FULL, Locale.SIMPLIFIED_CHINESE);
    }

    /**
     * get the date of the current year
     *
     * @return String
     */
    public static String getDay() {
        return String.valueOf(LocalDate.now().getDayOfYear());
    }


    /**
     * format date
     *
     * @param pattern
     * @return String
     */
    public static String formatDate(String pattern) {
        return LocalDate.now().format(DateTimeFormatter.ofPattern(StringUtils.isEmpty(pattern) ? DEFAULT_PATTERN_DATE_TIME : pattern));
    }

    /**
     * date to LocalDate
     *
     * @param date
     * @return LocalDate
     */
    public static LocalDate date2LocalDate(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).toLocalDate();
    }


    /**
     * localDate to date
     *
     * @param localDate
     * @return Date
     */
    public static Date localDate2Date(LocalDate localDate) {
        return Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * @return LocalDate
     * LocalDate <=format=> 2019-1-1
     * get the start of the month
     */
    public static String getCurrentMonthFirstDay() {
        return LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).
                format(DateTimeFormatter.ofPattern("yyyy-M-d"));
    }

    /**
     * @return LocalDate
     * LocalDate <=format=> 2019-01-31
     * get then end of the mouth
     */
    public static String getCurrentMonthLastDay() {
        return LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).format(DateTimeFormatter.ofPattern(DEFAULT_PATTERN_DATE));
    }


    public static String getCurrentDate(String pattern) {
        return LocalDate.now().format(DateTimeFormatter.ofPattern(pattern == null || pattern.equals("") ? DEFAULT_PATTERN_DATE : pattern));
    }

    public static String getCurrentDateTime(String pattern) {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(pattern == null || pattern.equals("") ? DEFAULT_PATTERN_DATE_TIME : pattern));
    }

    /**
     * get the month days
     * 1 3 5 7 8 10 12  <==> 31
     * 2 <==> 28 or 29
     * 4 6 9 11 <==> 30
     *
     * @return Integer
     */
    public static Integer getCurrentMonthDays() {
        return LocalDate.now().lengthOfMonth();
    }

    /**
     * get current month all date
     * 2018-01-01 2018-01-02 ... 2018-01-31
     *
     * @return List
     */
    public static List<Map<String, Object>> getCurrentMonthAllDate() {
        List<Map<String, Object>> list = new LinkedList<Map<String, Object>>() {{
            Map<String, Object> map;
            for (int i = 0; i < getCurrentMonthDays(); i++) {
                map = new ConcurrentHashMap<>();
                map.put("key", LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).plusDays(i).format(DateTimeFormatter.ofPattern(DEFAULT_PATTERN_DATE)));
                map.put("value", new Random().nextInt(30));
                add(map);
            }
        }};
        return list;
    }
}
